import BaseModel from '../BaseModel';
import ResourceTracker from '../tools/ResourceTracker';
import { loadByUrl } from '../tools/loader';
import * as THREE from 'three';

/**
 * TODO: 设备渲染数据
 */
export interface DeviceRawData {
  url: string;
  id: number | string;
  type: Editor.DeviceType;
  /** 当type为sideDevice时，需要附加sideType用于辅定位 */
  sideType?: Editor.AroundSideMeshKeys;
  /** 位姿数据 */
  pos: {
    /** 位置 */
    position: { x: number; y: number; z: number };
    /** 旋转 */
    quaternion: { x: number; y: number; z: number; w: number };
    /** 缩放*/
    scale: Editor.BaseModelScale;
  };
}

export default class Device extends BaseModel {
  /** 设备类型 */
  type: Editor.DeviceType;

  /** (MARK: 暂时没用)设备所在贴边类型 left | right | front | back */
  sideType?: Editor.AroundSideMeshKeys;

  /** 唯一id */
  id: number | string;

  /**
   * 构造函数
   * @param option - 设备配置选项
   */
  constructor(option: Editor.DeviceOption) {
    const { type, sideType, id = Date.now(), ...baseModelOption } = option;
    super(baseModelOption);
    this.type = type;
    this.id = id;
    sideType && (this.sideType = sideType);
  }

  override init(option: Editor.DeviceOption): Promise<THREE.Object3D | null> {
    const { url, group, pos, scale = {} } = option;
    this.scale = Object.assign(this.scale, scale);
    return new Promise((resolve, reject) => {
      loadByUrl(url)
        .then((model) => {
          this.resourceTracker = new ResourceTracker();
          this.resourceTracker.track(model);
          this.model = model;
          // 挂载到Bbuilding同级的group下
          group.add(model);

          // 依次转换pos
          if (pos) {
            const { position, quaternion, scale } = pos;
            this.model.position.set(position.x, position.y, position.z);
            this.model.quaternion.set(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
            this.changeScale(scale);
          }

          this._emitEvent(BaseModel.EVENT_BASEMODEL_LOADED, model);
          resolve(model);
        })
        .catch((e) => {
          console.error('[Device]-模型加载错误', e);
          this._emitEvent(BaseModel.EVENT_BASEMODEL_LOADED, null);
          reject(null);
        });
    });
  }

  // 获取保存数据
  getSaveData(): DeviceRawData {
    return {
      id: this.id,
      type: this.type,
      sideType: this.sideType,
      url: this.baseModelOption.url,
      pos: {
        position: {
          x: this.model.position.x,
          y: this.model.position.y,
          z: this.model.position.z,
        },
        quaternion: {
          x: this.model.quaternion.x,
          y: this.model.quaternion.y,
          z: this.model.quaternion.z,
          w: this.model.quaternion.w,
        },
        scale: this.scale,
      },
    };
  }
}
